package com.atguigu.gmall.order.mq;


import com.atguigu.gmall.common.constant.RabbitConstant;
import com.atguigu.gmall.common.util.JsonUtils;
import com.atguigu.gmall.model.to.mq.OrderCreateTo;
import com.atguigu.gmall.order.service.OrderInfoService;
import com.fasterxml.jackson.core.type.TypeReference;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;


/**
 * 订单关单监听器
 */
@Slf4j
@Service
public class OrderDeadListener {


    @Autowired
    OrderInfoService orderInfoService;
    /**
     *
     */
    //只要有人监听，需要使用，Rabbit中还没有的话就会自动创建
    @RabbitListener(queues= RabbitConstant.ORDER_DEAD_QUEUE)
    public void listenDeadOrder(Channel channel, Message message){
        //long deliveryTag, boolean multiple
        MessageProperties properties = message.getMessageProperties();
        long tag = properties.getDeliveryTag();
        OrderCreateTo mqOrder = null;
        try {

            //拿到MQ中订单消息数据
            mqOrder =
                    JsonUtils.converMessageToObject(message,new TypeReference<OrderCreateTo>(){});
            log.info("关闭订单：{}",mqOrder);
            //关闭订单（改订单为已取消状态） 乐观锁？
            //update order_info set order_status='CANCLE' where id={} and user_id={} and order_status='UNPAID'

            orderInfoService.closeTimeoutOrder(mqOrder.getOrderId(),mqOrder.getUserId());

            //消费端，手动确认模式。
            // 明确告诉服务器哪些消息已经收到并处理结束了，
            // 服务再删除这些消息，防止丢失
            // 因为默认不是 【手动确认模式】
            channel.basicAck(tag,false); //回复确认
        } catch (Exception e) {
            log.error("关单失败，原因：{}，订单：{}",e,mqOrder);
            try {
                //消息重新入队，让mq交给别人继续尝试消费
                channel.basicReject(tag,true);
            }catch (IOException exception){
                log.error("mq连接失败，原因：{}",exception);
            }

        }


    }
}
